{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2f177171-6fd2-487f-98d5-0d68c15dbcaa",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'pydotplus'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[2], line 4\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnp\u001b[39;00m\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msklearn\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m tree\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpydotplus\u001b[39;00m\n",
      "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'pydotplus'"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn import tree\n",
    "import pydotplus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bdcde8cc-3f41-46ff-a070-982eaf48efa4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def createTree(trainingData):\n",
    "    data = trainingData.iloc[:, :-1]  # 特征矩阵\n",
    "    labels = trainingData.iloc[:, -1]  # 标签\n",
    "    trainedTree = tree.DecisionTreeClassifier(criterion=\"entropy\")  # 使用信息熵划分\n",
    "    trainedTree.fit(data, labels)\n",
    "    return trainedTree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ce944cf-9698-4d35-81eb-71eac2092c96",
   "metadata": {},
   "outputs": [],
   "source": [
    "def showtree2pdf(trainedTree, filename):\n",
    "    dot_data = tree.export_graphviz(trainedTree, out_file=None)  # 导出为Graphviz格式\n",
    "    graph = pydotplus.graph_from_dot_data(dot_data)\n",
    "    graph.write_pdf(filename)  # 保存为PDF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c655a90-8bdd-4ab0-874b-fa43dcee2739",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 步骤4：定义数据向量化函数（类别转数值）\n",
    "def data2vector(data):\n",
    "    names = data.columns[:-1]\n",
    "    for i in names:\n",
    "        col = pd.Categorical(data[i])\n",
    "        data[i] = col.codes  # 将类别标签转为数值编码\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3173e31d-465f-4fb7-b0be-9fb0ebd95f41",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'pd' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;66;03m# 步骤5：调用函数进行训练和可视化\u001b[39;00m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;66;03m# 读取数据集（假设数据集文件为tennis.txt）\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[43mpd\u001b[49m\u001b[38;5;241m.\u001b[39mread_table(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtennis.txt\u001b[39m\u001b[38;5;124m\"\u001b[39m, header\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, sep\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;130;01m\\t\u001b[39;00m\u001b[38;5;124m'\u001b[39m)  \u001b[38;5;66;03m# 以制表符分隔\u001b[39;00m\n\u001b[1;32m      4\u001b[0m trainingvec \u001b[38;5;241m=\u001b[39m data2vector(data)  \u001b[38;5;66;03m# 向量化处理\u001b[39;00m\n\u001b[1;32m      5\u001b[0m decisionTree \u001b[38;5;241m=\u001b[39m createTree(trainingvec)  \u001b[38;5;66;03m# 生成决策树\u001b[39;00m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'pd' is not defined"
     ]
    }
   ],
   "source": [
    "# 步骤5：调用函数进行训练和可视化\n",
    "# 读取数据集（假设数据集文件为tennis.txt）\n",
    "data = pd.read_table(\"tennis.txt\", header=None, sep='\\t')  # 以制表符分隔\n",
    "trainingvec = data2vector(data)  # 向量化处理\n",
    "decisionTree = createTree(trainingvec)  # 生成决策树\n",
    "showtree2pdf(decisionTree, \"tennis.pdf\")  # 保存为PDF文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab1e157e-9634-47ab-a6c7-eed823bca44e",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.21"
  },
  "toc-autonumbering": true,
  "toc-showcode": false,
  "toc-showmarkdowntxt": false,
  "toc-showtags": false
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
